package com.augurit.gzcgwsp.wfex.common.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.jbpm.api.ProcessEngine;
import org.jbpm.api.history.HistoryTask;
import org.jbpm.pvm.internal.model.ProcessDefinitionImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.orm.Page;

import com.augurit.common.base.form.ResultForm;
import com.augurit.common.dao.AcRoleDao;
import com.augurit.common.dao.AcUserRoleDao;
import com.augurit.common.dao.SysCodeItemDao;
import com.augurit.common.entity.SysCodeItem;
import com.augurit.common.syscode.convert.SysCodeConverter;
import com.augurit.common.syscode.web.form.SysCodeForm;
import com.augurit.common.syslog.tool.SysTraceLogWriter;
import com.augurit.common.system.web.auth.form.LoginUserForm;
import com.augurit.common.util.HqlUtils;
import com.augurit.common.util.PageUtils;
import com.augurit.common.util.lang.StringUtils;
import com.augurit.common.workdayholiday.service.IWorkdayHolidayService;
import com.augurit.gzcgwsp.commonex.system.service.org.IOmOrgServiceEX;
import com.augurit.gzcgwsp.printDoc.service.IYwPrintDocService;
import com.augurit.gzcgwsp.sendNotice.entity.YwWebserviceInfo;
import com.augurit.gzcgwsp.sendNotice.entity.YwZhengwuInfo;
import com.augurit.gzcgwsp.sendNotice.service.IAcceptNoticeService;
import com.augurit.gzcgwsp.sendNotice.service.ICreateNoticeCommonPartService;
import com.augurit.gzcgwsp.sendNotice.service.IExchangeStateService;
import com.augurit.gzcgwsp.sendNotice.service.IYwSphjInfoService;
import com.augurit.gzcgwsp.sendNotice.service.IYwWebserviceInfoService;
import com.augurit.gzcgwsp.sendNotice.service.IYwZhengwuInfoService;
import com.augurit.gzcgwsp.smartformCsdlwj.common.SmartDao;
import com.augurit.gzcgwsp.ssgd.web.form.YwRqSsgdSqbForm;
import com.augurit.gzcgwsp.wfex.common.service.IWfServiceEX;
import com.augurit.gzcgwsp.wfex.common.util.WfUtilsEX;
import com.augurit.wf.bi.web.form.WfBusInstanceTaskForm;
import com.augurit.wf.common.constant.MsgConstant;
import com.augurit.wf.common.dao.Jbpm4HistProcinstDao;
import com.augurit.wf.common.dao.Jbpm4HistTaskDao;
import com.augurit.wf.common.entity.Jbpm4HistProcinst;
import com.augurit.wf.common.entity.Jbpm4HistTask;
import com.augurit.wf.common.entity.WfBusInstance;
import com.augurit.wf.common.service.IWfService;

@Service
@Transactional
public class WfServiceImplEX implements IWfServiceEX {
	private static final Logger logger=Logger.getLogger(WfServiceImplEX.class);
	@Autowired
	private ProcessEngine processEngine;
	@Autowired
	private IYwPrintDocService ywPrintDocService;
	@Autowired
	private IExchangeStateService exchangeStateService;
	@Autowired
	private Jbpm4HistTaskDao jbpm4HistTaskDao;	
	@Autowired
	private Jbpm4HistProcinstDao jbpm4HistProcinstDao;
	@Autowired
	private IWfService wfService;	
	@Autowired
	private IWorkdayHolidayService workdayHolidayService;	
	@Autowired
	private AcUserRoleDao acUserRoleDao;	
	@Autowired
	private AcRoleDao acRoleDao;	
	@Autowired
	private IOmOrgServiceEX omOrgServiceEX;	
	@Autowired
	private SmartDao smartDao;	
	@Autowired
	private ICreateNoticeCommonPartService createNoticeCommonPartService;	
	@Autowired
	private IAcceptNoticeService acceptNoticeService;	
	@Autowired
	private IYwWebserviceInfoService ywWebserviceInfoService;	
	@Autowired
	private IYwZhengwuInfoService ywZhengwuInfoService;	
	@Autowired
	private IYwSphjInfoService ywSphjInfoService;
	@Autowired
	private SysCodeItemDao sysCodeItemDao; //业务字典项DAO类
	public IWfService getWfService(){
		
		return this.wfService;
	}
	 /**
     * 计算开始日期经过几个工作日后的日期
     */
    public Date calculateDueDate3(Date startDate,String durationExpression){
    	logger.info("工作日天数表达式--->"+durationExpression);
    	if(startDate != null && durationExpression != null && durationExpression.trim().length()>0){
    		// 工作日问题 //
    	    //return processEngine.getTaskService().calculateDueDate(startDate, durationExpression);
    		//return Duration.calculateDueDate(startDate, durationExpression);
    	    //return processEngine.execute(new DurationCommon(startDate,durationExpression));
    	    //return workdayHolidayService.calculateDueDate(startDate, durationExpression);
    		
    		String[]  days=durationExpression.split(" ");
    		if(days.length>0){
    			try {
					Integer.valueOf(days[0]);
					return this.getReplyDate(startDate, Integer.valueOf(days[0]));
				} catch (NumberFormatException e) {
					logger.error("工作日天数出现问题"+e);
					e.printStackTrace();
				}
    			
    		}else{
    			String day=durationExpression.substring(0,2);
    			try {
					Integer.valueOf(days[0]);
					return this.getReplyDate(startDate, Integer.valueOf(day));
				} catch (NumberFormatException e) {
					logger.error("工作日天数出现问题"+e+"day-->"+day);
					e.printStackTrace();
				}
    		}
    		
        }
        return null;
    }
    
    /**
     * 计算开始日期经过几个工作日后的日期
     */
    public Date calculateDueDate3(Date startDate,Integer day){
    	if(startDate != null &&  day != null){
            //String durationExpression = day + " business day";
         // 工作日问题 //
            //return processEngine.getTaskService().calculateDueDate(startDate, durationExpression);
//            return Duration.calculateDueDate(startDate, durationExpression);
            //return processEngine.execute(new DurationCommon(startDate,durationExpression));
            //return workdayHolidayService.calculateDueDate(startDate, durationExpression);
            return this.getReplyDate(startDate, day);
            
        }
        return null;
    }
    
    /**
     * 计算开始日期经过几个工作日后的日期
     */
    public Date calculateDueDate(Date startDate,String durationExpression){
    	if(startDate != null && durationExpression != null && durationExpression.trim().length()>0){
    		// 工作日问题 //
    	    //return processEngine.getTaskService().calculateDueDate(startDate, durationExpression);
    		//return Duration.calculateDueDate(startDate, durationExpression);
    	    //return processEngine.execute(new DurationCommon(startDate,durationExpression));
    	    return workdayHolidayService.calculateDueDate(startDate, durationExpression);
        }
        return null;
    }
    
    /**
     * 计算开始日期经过几个工作日后的日期
     */
    public Date calculateDueDate(Date startDate,Integer day){
    	if(startDate != null &&  day != null){
            String durationExpression = day + " business day";
         // 工作日问题 //
            //return processEngine.getTaskService().calculateDueDate(startDate, durationExpression);
//            return Duration.calculateDueDate(startDate, durationExpression);
            //return processEngine.execute(new DurationCommon(startDate,durationExpression));
            return workdayHolidayService.calculateDueDate(startDate, durationExpression);
        }
        return null;
    }
    
    /**
     * 计算两个日期之间的工作日得天数,要求是两个日期之间最多只能相差366天
     */
    public Integer calculateBussinessDays(Date startDate,Date endDate){
        if(startDate != null && endDate != null){
        	// 工作日问题 //
//        	return processEngine.getTaskService().calculateBussinessDays(startDate, endDate);
            return workdayHolidayService.calNumOfWorkDays(startDate, endDate);
            
        }
        return -1;
    }
    
    /**
     * 根据taskInstDbid获取流程时限的表达式
     * @param taskInstDbid
     * @return
     */
    public String getProcDueExpressIonByTaskInstDbid(Long taskInstDbid){
        String durationExpression = null;
        if(taskInstDbid != null){
        	HistoryTask task =this.processEngine.getHistoryService().createHistoryTaskQuery().taskId(taskInstDbid.toString()).uniqueResult();
            ProcessDefinitionImpl pdf = this.wfService.getProcDefByProcInstId(task.getProcInstId());
            durationExpression = pdf.getProcessDuedateDescription();
            
        }
        return durationExpression;
    }

	public List getHandleCommentsByTaskInstDbidAndActivityNames(
			Long taskInstDbid, String names) {
		List<Jbpm4HistTask> list = null;
		if(taskInstDbid != null){
			
			StringBuffer hql = new StringBuffer("select h from Jbpm4HistTask h, Jbpm4Task t where " +
					"h.execution = t.executionId and t.taskInstDbid = " + taskInstDbid+" order by h.histTaskInstDbid asc");
			if(names != null){
					//hql.append(" and h.activityName in (" + names + ")");
			}
			list = jbpm4HistTaskDao.find(hql.toString());
		}
		return list;
	}
	
	/**
	 * 根据开始时间计算和天数计算答复时间
	 * @param startDate
	 * @param day
	 * @return
	 */
	public Date getReplyDate(Date startDate,int day){
		Date date=null;
		int days=day-1;
		long daymillion=24*60*60*1000;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		try {
			long a=startDate.getTime();
			long b=a+(days/5*7)*daymillion;
			int daysleft=days%5;
			for(int i=0;i<daysleft;i++){
				b+=daymillion;
				Calendar c=Calendar.getInstance();
				c.setTimeInMillis(b);
				if(c.get(Calendar.DAY_OF_WEEK)>=6)
					i--;
			}
			String enddate=sdf.format(new Long(b));
			date=sdf.parse(enddate);
			
		} catch (Exception e) {
			logger.error("计算工作日时间解析错误"+e);
			e.printStackTrace();
		}
		return date;
	}
	
	
	public static void main(String[] args) { 
		String datetopase="2012-05-24";
		int days=Integer.parseInt("20")-1;
		long daymillion=24*60*60*1000;
		SimpleDateFormat bartDateFormat = new SimpleDateFormat("yyyy-MM-dd");
		try {
			Date date = bartDateFormat.parse(datetopase);
			long a=date.getTime();
			int s=days/5*7;
			long b=a+(days/5*7)*daymillion;
			
			int daysleft=days%5;
			for(int i=0;i<daysleft;i++){
				b+=daymillion;
				Calendar c=Calendar.getInstance();
				c.setTimeInMillis(b);
				int week=c.get(Calendar.DAY_OF_WEEK);
				if(c.get(Calendar.DAY_OF_WEEK)>=6)
					i--;
			}
			System.out.println(bartDateFormat.format(new Long(b))); 
		} catch (Exception e) {
			e.printStackTrace();
		}
	//}

//		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
//		sdf.format(new Date());
//		long beginTime=new Date().getTime(); 
//		long stepTime=24*60*20*1000; 
//		Date dt; 
//		int dy; 
//		Long endTime=beginTime; 
//		int k=0; 
//		while(k<60){ 
//			endTime+=stepTime; 
//			dt=new Date(endTime); 
//			dy=dt.getDay(); 
//			if(dy!=0&&dy!=6){ 
//			k++; 
//			} 
//		} 
//		
//		
//		String needDate = new SimpleDateFormat("yyyy-MM-dd").format(endTime); 
//		System.out.println("不算3月1号到："+needDate+"满20个工作日。"); 

		}
	
	
	
	/**
	 * 根据【人员所属地区数字编码】和【角色编码】 获取人员
	 * 只能配一个，因为userIdList只拿一个；如果要配多个，就要拿多个，好像是用逗号隔开
	 * @param roleCode  角色编码
	 * @param areaCode  人员所属地区数字编码
	 * @return
	 */
	public String getUser(String roleCode,String areaCode){
		//************自己的业务逻辑 开始************
		String hql="select ps.roleId from AcRole ps where ps.roleCode='"+roleCode+"'";
		List<Long> roleIds = acRoleDao.find(hql);//通过编码获取角色编号
		String sql = "select u.login_name from Ac_User_Role ps,OM_USER u where ps.role_Id='"+roleIds.get(0)+"' and ps.user_id=u.user_id ";
		if(StringUtils.isNotEmpty(areaCode)){
			sql = sql + " and u.remark='"+areaCode+"'";
		}
		SQLQuery SQLQuery = acUserRoleDao.getSession().createSQLQuery(sql);

		List userIdList = SQLQuery.list();
		String assignee="";
		if(userIdList.size()>0){
			assignee = (String)userIdList.get(0);
		}
		System.out.println("获取启动者 = "+assignee);
//		String assignee="";
//		if(userIdList!=null){
//			List<OmUser> users = userDao.findByIds(userIdList);
//			for(OmUser user : users){
//				assignee+=user.getUserCode()+",";
//			}
//		}
//		
//		assignee=assignee.substring(0, assignee.length()-1);
		
		//************自己的业务逻辑 结束************
//		
		return assignee;
	}
	
	/**
	 * 
	 * @param id   用户id
	 * @param roleId   角色id，通过代码写定
	 * @return
	 */
	public String findBoPlaceCode(Long id, Long roleId){
		String idStr = "";
		if(id != null){
			idStr = id.toString();
		}
		return omOrgServiceEX.getUserByDistrictCodeAndRole(idStr, roleId);
	}
	
	/**
     * 通过procInstId获取延期天数
     * @param procInstId
     * @return
     */
    public int getYqtsByProcInstId(String procInstId){
    	int yqts = 0;
    	String sql = "select t.bus_num1 from wf_bus_instance t where t.proc_Inst_Id='"+procInstId+"'";
    	List list = smartDao.getResultList(sql);
    	if(list != null && list.size()>0){
    		Object obj = list.get(0);
    		BigDecimal s = (BigDecimal) obj;
    		if(s != null){
    			yqts = s.intValue();
    		}			
    	}
    	return yqts;
    }
    
    /**
     * 延期时，更新到期时间
     * @param procInstId
     * @param yqts 					延期天数
     * @param startDate 			收案日期
     * @param durationExpression	审批时限
     * @return
     */
    public Date updateProcessDutedateByProcInstIdAndYqts(String procInstId,int yqts,Date startDate,String durationExpression){
    	System.out.println("审批时限 = "+durationExpression);
    	System.out.println("延期"+yqts+"工作日");
    	String oldSpsx =  durationExpression.split(" ")[0];//旧的审批时限
    	String newSpsx = String.valueOf(Integer.parseInt(oldSpsx) + yqts);
    	String newDurationExpression = newSpsx + " business day";
    	Date dutedate = this.calculateDueDate(startDate, newDurationExpression);
    	saveProcessDutedateByProcInstId(procInstId,dutedate,yqts);
    	return dutedate;
    }
       
    /**
     * 把延期或者做了补正材料通知书后的答复时间保存到数据库
     * @param procInstId
     * @param timestamp
     */
    public void saveProcessDutedateByProcInstId(String procInstId,Date date,int yqts){
    	SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    	String dutedate = dateFormat.format(date);
    	System.out.println("dutedate = "+dutedate);
    	String s = "to_date('"+dutedate+"','yyyy-mm-dd hh24:mi:ss')";
    	String sql = "update jbpm4_hist_procinst t set t.process_duedate="+s+" where t.id_='"+procInstId+"'";
    	smartDao.executeSql(sql);
    	saveBusNum1(procInstId, yqts);
    }
    
    /**
     * 保存延期天数
     * @param procInstId
     * @param yqts
     */
    public void saveBusNum1(String procInstId,int yqts){
    	String sql = "update wf_bus_instance t set t.bus_num1='"+yqts+"' where t.proc_inst_id='"+procInstId+"'";
    	smartDao.executeSql(sql);
    }
    
    /**
     * 通过受理号，从wf_bus_instance表查询延期天数
     * @param acceptNo
     * @return
     */
    public int getBusNum1(String acceptNo){
    	int yqts = 0;
    	String sql = "select t.bus_num1 from wf_bus_instance t where t.bus_memo3='"+acceptNo+"'";
    	List list = smartDao.getResultList(sql);
    	if(list != null && list.size()>0){
    		Object obj = list.get(0);
    		BigDecimal s = (BigDecimal) obj;
    		if(s != null){
    			yqts = s.intValue();
    		}			
    	}
    	return yqts;
    }
    
    /**
     * 根据id获取代理人
     * @param id
     * @return
     */
    public List getAgentNameById(long id){
    	String sql = "select t.agent,t.agent_name from jbpm4_hist_task t where t.dbid_='"+id+"'";
    	List list = smartDao.getResultList(sql);
    	return list;
    }
    
    /**
     * 根据id获取Jbpm4HistTask
     * @param id
     * @return
     */
    public Jbpm4HistTask getJbpm4HistTaskById(long id){
    	String hql = "from Jbpm4HistTask ps where ps.histTaskInstDbid='"+id+"'";
    	System.out.println("hql ============== "+hql);
		Query query = smartDao.getSession().createQuery(hql);
		List<Jbpm4HistTask> list = query.list();
		Jbpm4HistTask instance = list.get(0);
		return instance;
    }
    
    /**
	 * 根据延期和补正材料告知书算出结案时间
	 * @param procInstId
	 * @param yqts
	 * @param larq
	 * @param durationExpression
	 * @param bjgzsj 
	 * @return
	 */
	public Date getDfsjByYqtsAndBjgzsj(String procInstId,int yqts,Date larq,String durationExpression,Date bjgzsj,IWfServiceEX wfServiceEX){
		Date dfsj = null;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Calendar cal =Calendar.getInstance();
		try {
			if(yqts >= 0 && bjgzsj == null){//没做补正材料通知书，没延期或者有延期
				dfsj = wfServiceEX.updateProcessDutedateByProcInstIdAndYqts(procInstId,yqts,larq,durationExpression);
				System.out.println("立案日期 = "+sdf.format(larq));
				System.out.println("没做补正材料通知书，没延期或者有延期");
				System.out.println("延期 = " + yqts + " 工作日");
			    System.out.println("结案日期 = "+sdf.format(dfsj));
			}else if(bjgzsj != null && yqts == 0){//做了补证材料通知书，没延期       结案时间 =  补正材料通知书的日期 + 30个自然日 + 延期工作日	
				System.out.println("补证材料通知书日期 = "+sdf.format(bjgzsj));
			    cal.setTime(bjgzsj);
			    cal.set(Calendar.DATE,cal.get(Calendar.DATE)+30);//加30个自然日
			    cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 17, 30);//设置为下班时间17：30分
			    Date dateAfter30 = cal.getTime();
			    System.out.println("补证材料通知书加30自然日后 ======= "+sdf.format(dateAfter30));
			    dfsj = wfServiceEX.calculateDueDate(dateAfter30,10);//加10个工作日			    
			    System.out.println("做了补正材料通知书，没延期");			    
			    System.out.println("结案时间 = "+sdf.format(dfsj));
			    this.saveProcessDutedateByProcInstId(procInstId, dfsj, yqts);
			}else if(bjgzsj != null && yqts > 0){//做了补正材料通知书，有延期      结案时间 =  补正材料通知书的日期 + 30个自然日 + 10个工作日 + 延期工作日
				System.out.println("补证材料通知书日期 = "+sdf.format(bjgzsj));
			    cal.setTime(bjgzsj);
			    cal.set(Calendar.DATE,cal.get(Calendar.DATE)+30);//加30个自然日
			    cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 17, 30);//设置为下班时间17：30分
			    Date dateAfter30 = cal.getTime();
			    System.out.println("补证材料通知书加30自然日后 ======= "+sdf.format(dateAfter30));
			    Date dateAfter30And10 = wfServiceEX.calculateDueDate(dateAfter30,10);//加10个工作日
			    System.out.println("补证材料通知书加30自然日后，再加10个工作日后 = "+sdf.format(dateAfter30And10));
			    dfsj = wfServiceEX.calculateDueDate(dateAfter30And10,yqts);//加延期工作日
			    System.out.println("做了补正材料通知书，有延期");	
			    System.out.println("延期 = " + yqts + " 工作日");
			    System.out.println("结案日期 = "+sdf.format(dfsj));
			    this.saveProcessDutedateByProcInstId(procInstId, dfsj, yqts);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}		
		return dfsj;
	}

	/*
	 * (non-Javadoc)
	 * @see com.augurit.gzcgwsp.wfex.common.service.IWfServiceEX#contentByTaskId(java.lang.Long, java.lang.String, java.lang.String)
	 */
	@Override
	public List<Jbpm4HistTask> contentByTaskId(String execution, String activeName) {
		String hql="from Jbpm4HistTask where execution='"+execution+"'";
		if(StringUtils.isNotBlank(activeName)){
			hql+=" and activityName in ("+ activeName + ")";
		}
		List<Jbpm4HistTask> list=this.jbpm4HistTaskDao.find(hql);
		return list;
	}
	/*
	 * (non-Javadoc)
	 * @see com.augurit.gzcgwsp.wfex.common.service.IWfServiceEX#checkBjData(java.lang.String, java.lang.String)
	 */
	@Override
	public boolean checkBjData(String templteCode, String masterEntityKey) {
		Map map=exchangeStateService.getMapByTemplate(templteCode, masterEntityKey);
		if(map != null){
			String serialNo=(String) map.get("serialNo");
			if(StringUtils.isBlank(serialNo)){
				serialNo=(String) map.get("acceptNo");
			}
			String sql=" from YwZhengwuInfo where serialNo='"+serialNo+"' and sphjdmmc='补交告知'";
			List list=this.jbpm4HistTaskDao.find(sql);
			if(map!=null){
				String bjgzyy=(String) map.get("bjgzyy");//补交告知原因
				String bjgzqd=(String) map.get("bjgzqd");//补交告知清单
				String bjclqdstr=(String) map.get("bjclqd");//补交受理材料清单
				//发送的时候如果有补交告知清单要提醒补交受理材料没保存
				if(list.size()>0){//与政务办数据对接
					//存在补交告知
					String bjclqd=(String) map.get("bjclqd");
					if(StringUtils.isBlank(bjclqd)){
						return true;
					}
				}else{//没有与政务办数据对接
					if(StringUtils.isNotBlank(bjgzyy) && 
							StringUtils.isNotBlank(bjgzqd)){
						if(StringUtils.isBlank(bjclqdstr)){
							return true;
						}
					}
				}

			}
			return false;
		}
		
		return false;
	}
	
	/**
	 * 查询相应的业务表，判断bjslsj是否为空
	 * @param templateCode
	 * @param masterEntityKey
	 * @return
	 */
	public boolean checkBjslsjByTemplateCodeAndYwId(String templateCode, String masterEntityKey){
		String databaseName = this.getDatabaseNameByTemplateCode(templateCode);
		if(StringUtils.isNotBlank(databaseName)){
			String sql = "select t.* from "+databaseName+" t where t.id='"+masterEntityKey+"' and t.bjslsj is not null and t.bjclqd  is not null";
			List list=this.jbpm4HistTaskDao.getSession().createSQLQuery(sql).list();
			if(list != null && list.size()>0){
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 根据templateCode获取数据库表名
	 * @param templateCode
	 * @return
	 */
	public String getDatabaseNameByTemplateCode(String templateCode){
		String sql = "select t.slave_entities from WF_BUS_TEMPLATE t where t.TEMPLATE_CODE='"+templateCode+"'";
		List list=this.jbpm4HistTaskDao.getSession().createSQLQuery(sql).list();
		if(list != null && list.size()>0){
			return (String)list.get(0);
		}
		return null;
	}
	
	/**
	 * 根据templateCode获取templateName
	 * @param templateCode
	 * @return 
	 */
	public String getTemplateNameByTemplateCode(String templateCode){
		String sql = "select template_Name from WF_BUS_TEMPLATE t where t.TEMPLATE_CODE='"+templateCode+"'";
		List list=this.jbpm4HistTaskDao.getSession().createSQLQuery(sql).list();
		if(list != null && list.size()>0){
			return (String)list.get(0);
		}
		return null;
	}
	
	/*
	 * 发送(non-Javadoc)
	 * @see com.augurit.gzcgwsp.wfex.common.service.IWfServiceEX#wfSend(com.augurit.wf.bi.web.form.WfBusInstanceTaskForm)
	 */
	@Override
	public ResultForm wfSend(WfBusInstanceTaskForm instance,LoginUserForm user) {
		//先检测选择用户是否正确
		ResultForm result = wfService.validateSelectedAssignee(instance);
		logger.info("开始发送-------");
		if(result.isSuccess()){
			//如果是窗口发送，重新生成受理号
			String ywId = instance.getMasterEntityKey();
			String templateCode = instance.getTemplateCode();
			Long taskInstDbid = instance.getTaskInstDbid();
			Jbpm4HistTask thisInstance = jbpm4HistTaskDao.get(taskInstDbid);//这个节点对象
			String nowActivityName = thisInstance.getActivityName();//这个节点的英文名称
			if("cksa".equals(nowActivityName)){
				WfBusInstance inst=this.getInst(ywId, templateCode);
				String area=inst.getBusMemo2();
				if(StringUtils.isBlank(area)){//非区的案件重新生成受理号码
					Date date4=inst.getBusDate4();
					if(date4==null){
						ywPrintDocService.updateAcceptNo(templateCode, ywId);
					}
				}else{//修改区的受理号
					Date date4=inst.getBusDate4();
					if(date4==null){
					  ywPrintDocService.updateQuAcceptNo(templateCode, ywId, getAcceptNo(ywId, templateCode));
					}
				}
			}
			wfService.send(instance);
			result.setErrMsg(MsgConstant.getSendSuccessMsg(instance.getDestActivityChineseName(), instance.getAssigneeName()));
			//WfUtils.clearWfSendInfo(instance);	
			try {
				exchangeStateService.sendSmsInfo(taskInstDbid);//提前一天通知经办人(户外广告)
			} catch (RuntimeException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			try{//案件状态交换
				logger.info("------ 发送时，案件状态交换已经打开 -------------------");
				exchangeStateService.exchangeState(user, instance);
				//补交受理
				//exchangeStateService.saveBjsl(user, instance); 
			    
			}catch(Exception e){
				e.printStackTrace();
			}
			//开始改时间主要是针对提交了补交告知没有提交补交受理的情况
			if("jbrsl".equals(nowActivityName)||
					"jbrcs".equals(nowActivityName)||"jbryskc".equals(nowActivityName)
					||"xyzxjbr".equals(nowActivityName) || 
					"jbryj".equals(nowActivityName) ||"fqwzxjbr".equals(nowActivityName)){
				boolean flag=this.checkBjData(templateCode,ywId);
				if(flag){
					//改时间
					String durationExpression = this.getProcDueExpressIonByTaskInstDbid(taskInstDbid);
					int days =  Integer.parseInt(durationExpression.split(" ")[0]);
		        	String sql = "from Jbpm4HistProcinst t where t.procInstId='"+thisInstance.getProcInstId()+"'";
		    		List list=jbpm4HistProcinstDao.find(sql);
		    		if(list.size()>0){
			    		Jbpm4HistProcinst proc=(Jbpm4HistProcinst) list.get(0);
			    		Date newDate=this.calculateDueDate(new Date(),days);
			    		proc.setProcessDuedate(newDate);
			    		jbpm4HistTaskDao.getSession().update(proc);
				}
			}
		}
			
		}
		return result;
	}
	/**
	 * 获取受理号
	 * @param ywId
	 * @param templateCode
	 * @return
	 */
	private String getAcceptNo(String ywId,String templateCode){
		String hql="select ins from  WfBusInstance ins,WfBusTemplate temp where temp.id=ins.templateId" +
				" and ins.masterEntityKey="+Long.valueOf(ywId)+" and temp.templateCode='"+templateCode+"'";
		List list=this.jbpm4HistTaskDao.find(hql);
		if(list.size()>0){
			WfBusInstance inst=(WfBusInstance) list.get(0);
			if(inst!=null){
				String acceptNo=inst.getBusMemo3();
				return acceptNo;
			}
		}
		return null;
	}
	
	/**
	 * 获取区域
	 * @param ywId
	 * @param templateCode
	 * @return
	 */
	private WfBusInstance getInst(String ywId,String templateCode){
		String hql="select ins from  WfBusInstance ins,WfBusTemplate temp where temp.id=ins.templateId" +
				" and ins.masterEntityKey="+Long.valueOf(ywId)+" and temp.templateCode='"+templateCode+"'";
		List list=this.jbpm4HistTaskDao.find(hql);
		if(list.size()>0){
			WfBusInstance inst=(WfBusInstance) list.get(0);
			if(inst!=null){
				return inst;
			}
		}
		return null;
	}
	
	
	/**
	 * 获取区域
	 * @param ywId
	 * @param templateCode
	 * @return
	 */
	private String getArea(String ywId,String templateCode){
		String hql="select ins from  WfBusInstance ins,WfBusTemplate temp where temp.id=ins.templateId" +
				" and ins.masterEntityKey="+Long.valueOf(ywId)+" and temp.templateCode='"+templateCode+"'";
		List list=this.jbpm4HistTaskDao.find(hql);
		if(list.size()>0){
			WfBusInstance inst=(WfBusInstance) list.get(0);
			if(inst!=null){
				String area=inst.getBusMemo2();
				return area;
			}
		}
		return null;
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.augurit.gzcgwsp.wfex.common.service.IWfServiceEX#getDfsjByTempleteCode(java.lang.String, java.lang.Long)
	 */
	@Override
	public Date getDfsjByTempleteCode(String templateCode, Long id) {
		String hql=" select proc from WfBusInstance inst,Jbpm4HistProcinst proc ,WfBusTemplate template where inst.procInstId=proc.procInstId " +
		" and inst.masterEntityKey='"+id+"' and inst.templateId=template.id and template.templateCode='"+templateCode+"'";
		List list=this.jbpm4HistTaskDao.find(hql);
		if(list.size()>0){
			Jbpm4HistProcinst proc=(Jbpm4HistProcinst) list.get(0);
			if(proc!=null){
				return proc.getProcessDuedate();
			}
		}
		
		return null;
	}

	/**
     * 启动公示
     * @param ywRqSsgdSqbForm
     * @return 
     * @throws Exception
     */
	public void startPublic(YwRqSsgdSqbForm form,Long taskInstDbid,WfBusInstanceTaskForm instance,LoginUserForm loginuserForm,Date endDate,String gssj) throws Exception{
		Locale locale = Locale.getDefault(); 
		ResourceBundle localResource = ResourceBundle.getBundle("interfaceExchange", locale); 
//		Long taskInstDbid = instance.getTaskInstDbid();
		System.out.println("taskInstDbid ============== "+taskInstDbid);
		instance.setTaskInstDbid(taskInstDbid);
		Jbpm4HistTask thisInstance = getJbpm4HistTaskById(taskInstDbid);//这个节点对象
		Date acceptTime = exchangeStateService.getAcceptTime(thisInstance);		
		//保存开始公示要发送的交换数据到数据库   ---------------------开始
		String loginUserName = loginuserForm.getUser().getUserName();
		//获得部门
		String dpm = loginuserForm.getOrg().getOrgName();
		
		Map<String,String> noticeMap = acceptNoticeService.getCommonAcceptNoticeMap(form.getSqrq(), form.getAcceptNo(), form.getCbyw(), form.getYwlxr(), form.getSjr(), form.getSqdw(), instance);
		String notice = acceptNoticeService.createAcceptNotice(noticeMap);		
		//获得设施改动标签与值对应map   每个都不一样
//		Map<String,String> noticeLabelMap = createNoticeCommonPartService.getSsgdNoticeLabel(ywRqSsgdSqbForm, instance, loginUserName, dpm, "ajgs","案件公示", notice,acceptTime);
		Map<String,String> noticeLabelMap = createNoticeCommonPartService.getCommonNoticeLabel(form.getApprovalNo(), form.getAcceptNo(), 
				form.getBusinessCode(), form.getSqdw(), form.getCbyw(), instance, loginUserName, dpm, "ajgs", "案件公示", notice, acceptTime);
		//调用发送方法   每个都一样
		//createNoticeCommonPartService.sendNotice2(map);
		YwWebserviceInfo ywWebserviceInfo = ywWebserviceInfoService.createYwWebserviceInfo(noticeLabelMap,false,form.getAcceptNo(),form.getApprovalNo());
		ywWebserviceInfo.setProduceDate(new Date());
		ywWebserviceInfoService.save(ywWebserviceInfo);
		//保存开始公示要发送的交换数据到数据库   ---------------------结束
		//保存自动结束公示要发送的交换数据到数据库   ---------------------开始
		saveAutomaticEndPublic(form, endDate);
		//保存自动结束公示要发送的交换数据到数据库   ---------------------开始
		
		String sxbm = "";
		try {
			sxbm = localResource.getString(form.getTemplateCode());
		} catch (Exception e) {
			e.printStackTrace();
		}
		Map<String,String> map=exchangeStateService.buildMap(loginuserForm, taskInstDbid, form.getId().toString(), form.getTemplateCode(), false);
		if(map == null){
			map = new HashMap<String,String>();
		}
		map.put("sxbm", sxbm);
		map.put("yqts", gssj);
		map.put("yqly", "案件公示");
		System.out.println("form.getId().toString() ============== "+form.getId().toString());
		WfUtilsEX.tbcxStart(form.getAcceptNo(), form.getPassword(), sxbm, form.getId().toString(), loginUserName,form.getTemplateCode(),ywZhengwuInfoService,ywSphjInfoService,this,map,endDate);

	}
	
	/**
     * 启动公示时，保存7天后自动结束公示的记录到ywWebserviceInfo表
     * @param ywRqSsgdSqbForm
     * @return 
     * @throws Exception
     */
	public void saveAutomaticEndPublic(YwRqSsgdSqbForm ywRqSsgdSqbForm,Date endDate) throws Exception{
		Locale locale = Locale.getDefault(); 
		ResourceBundle localResource = ResourceBundle.getBundle("interfaceExchange", locale); 
		String xmlString = createNoticeCommonPartService.createStopPublicXMLString(ywRqSsgdSqbForm.getAcceptNo());
		YwWebserviceInfo ywWebserviceInfo = new YwWebserviceInfo();
//		ywWebserviceInfo.setFilePath(xmlString);//把xml格式的字符串保存到FilePath字段中
		ywWebserviceInfo.setXmlStr(xmlString);
		String wsdl = localResource.getString("fxwsdl");
		String SPXT_ApprovalInfoFeedBack_Service = localResource.getString("SPXT_ApprovalInfoFeedBack_Service");
		String stopPublicApprovalInfo = localResource.getString("stopPublicApprovalInfo");
		ywWebserviceInfo.setWsdlPara(wsdl);
		ywWebserviceInfo.setParaTwo(SPXT_ApprovalInfoFeedBack_Service);
		ywWebserviceInfo.setParaThree(stopPublicApprovalInfo);
		ywWebserviceInfo.setProduceDate(new Date());
		ywWebserviceInfo.setAcceptNo(ywRqSsgdSqbForm.getAcceptNo());
		ywWebserviceInfo.setEndDate(endDate);
		ywWebserviceInfo.setParaFour(ywRqSsgdSqbForm.getApprovalNo());
		ywWebserviceInfoService.save(ywWebserviceInfo);
		//保存要发送的交换数据到数据库   ---------------------结束
	}
	
	/**
     * 停止公示
     * @param acceptNo
     * @return 
     * @throws Exception
     */
	public void stopPublic(String acceptNo,String approvalNo) throws Exception{
		
		//保存要交换到方欣的数据到数据库 -----------------------开始
		Locale locale = Locale.getDefault(); 
		ResourceBundle localResource = ResourceBundle.getBundle("interfaceExchange", locale); 
		String xmlString = createNoticeCommonPartService.createStopPublicXMLString(acceptNo);
		YwWebserviceInfo ywWebserviceInfo = ywWebserviceInfoService.getStopYwWebserviceInfoByAcceptNo(acceptNo);
		if(ywWebserviceInfo == null){
			ywWebserviceInfo = new YwWebserviceInfo();
		}
//		ywWebserviceInfo.setFilePath(xmlString);//把xml格式的字符串保存到FilePath字段中
		ywWebserviceInfo.setXmlStr(xmlString);
		String wsdl = localResource.getString("fxwsdl");
		String SPXT_ApprovalInfoFeedBack_Service = localResource.getString("SPXT_ApprovalInfoFeedBack_Service");
		String stopPublicApprovalInfo = localResource.getString("stopPublicApprovalInfo");
		ywWebserviceInfo.setWsdlPara(wsdl);
		ywWebserviceInfo.setParaTwo(SPXT_ApprovalInfoFeedBack_Service);
		ywWebserviceInfo.setParaThree(stopPublicApprovalInfo);
//		ywWebserviceInfo.setProduceDate(new Date());
		ywWebserviceInfo.setEndDate(new Date());
		ywWebserviceInfo.setAcceptNo(acceptNo);
		ywWebserviceInfo.setParaFour(approvalNo);
		ywWebserviceInfo.setParaFive("手动结束公示");
		ywWebserviceInfoService.save(ywWebserviceInfo);
		//保存要交换到方欣的数据到数据库   ---------------------结束
		
		//修改要交换到政务中心的数据------------------------开始
		YwZhengwuInfo ywZhengwuInfo = ywZhengwuInfoService.getYwZhengwuInfoBySerialNoAndSphjdm(acceptNo, "012");
		if(ywZhengwuInfo != null){
			ywZhengwuInfo.setIsSended(null);
			ywZhengwuInfoService.save(ywZhengwuInfo);
		}
		//修改要交换到政务中心的数据------------------------开始
		
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.augurit.gzcgwsp.wfex.common.service.IWfServiceEX#getWorkDays(java.util.Date, java.util.Date)
	 */
	@Override
	public int getWorkDays(Date startDate, Date endDate) {
	      if(startDate != null && endDate != null){
	        	// 工作日问题 //
//	        	return processEngine.getTaskService().calculateBussinessDays(startDate, endDate);
	            return workdayHolidayService.getWorkDays(startDate, endDate);
	            
	        }
	        return -1;
	}
	
	/**
	 * 根据templateCode获取当前流程图
	 * @param templateCode
	 * @return
	 */
	public String getCurrentFlowByTemplateCode(String templateCode){
		StringBuffer sql = new StringBuffer();
		sql.append("select bt.wf_def_key ,bt.wf_def_version ");   
		sql.append(" from wf_bus_template bt, wf_bus_template_type btt ");
		sql.append(" where bt.template_type_id = btt.id ");
		sql.append(" and bt.template_code = '"+templateCode+"'");
		List list = smartDao.getSession().createSQLQuery(sql.toString()).list();
		String currentFlow = "";
		if(list != null && list.size() > 0){
			String code = (String)((Object [])list.get(0))[0];
			String no = ((BigDecimal)((Object [])list.get(0))[1]).toString();
			currentFlow = code + "-" + no;
		}
		System.out.println("currentFlow = "+currentFlow);
		return currentFlow;
	}
	
	/**
	 * 根据templateCode获取当前流程图的时间
	 * @param templateCode
	 * @return
	 */
	public String getDurationExpressionByTemplateCode(String templateCode){
		String durationExpression = null;
		String procdefid_ = this.getCurrentFlowByTemplateCode(templateCode);
		if(StringUtils.isNotBlank(procdefid_)){
			StringBuffer sql = new StringBuffer();
			sql.append("select t.id_ from JBPM4_HIST_PROCINST t where t.procdefid_='"+procdefid_+"' and t.state_='active'");
			List list = smartDao.getSession().createSQLQuery(sql.toString()).list();
			String procInstId = null;
			if(list != null && list.size() > 0){
				procInstId = (String)list.get(0);
				if(procInstId != null){
						ProcessDefinitionImpl pdf = this.wfService.getProcDefByProcInstId(procInstId);
			            durationExpression = pdf.getProcessDuedateDescription();
			            System.out.println("durationExpression = "+durationExpression);
				}
			}
		}
		if(StringUtils.isBlank(durationExpression)){//该流程还没有收过案，查不到，则从系统的数据字典里面查
			durationExpression = getItemNameByItemCodeAndTypeCode(templateCode,"WF_FLOW_DATE").getItemName();
			System.out.println("durationExpression2 = "+durationExpression);
		}
		return durationExpression;
	}
	
	/**
	 * 根据ItemCode和typeCode获取ItemName(ItemCode不能重复)
	 * @param ItemCode
	 * @param typeCode
	 * @return
	 */
	public SysCodeForm getItemNameByItemCodeAndTypeCode(String ItemCode,String typeCode){
		SysCodeForm form = new SysCodeForm();
		form.setItemCode(ItemCode);
		form.setTypeCode(typeCode);
		Page<SysCodeForm> page = new Page<SysCodeForm>(10);
		this.searchItem(page, form);
		SysCodeForm sysCodeForm = null;
		if(page.getResult() == null){
			return null;
		}
		if(page.getResult() != null && page.getResult().size() > 0){
//			itemName = page.getResult().get(0).getItemName();
			sysCodeForm = page.getResult().get(0);
		}else{
			logger.error("查数据字典错误："+SysTraceLogWriter.MESSAGE_SEPARATOR+"数据字典类型编号为"+typeCode+"中没有对应子项的ItemCode值为:"+ItemCode);
		}
		return sysCodeForm;
	}
	
	/**
	 * 根据templateCode获取templateName
	 * @param templateCode
	 * @return
	 */
	public String getSxmcByTemplateCode(String templateCode){
		StringBuffer sql = new StringBuffer();
		sql.append("select t.slave_entities from WF_BUS_TEMPLATE t where t.template_code='"+templateCode+"'");
		List list = smartDao.getSession().createSQLQuery(sql.toString()).list();
		if(list != null && list.size() > 0){
			String slave_entities = (String)list.get(0);
			StringBuffer sql2 = new StringBuffer();
			sql2.append("select t.memo from sys_meta_table t where t.table_name='"+slave_entities+"'");
			List list2 = smartDao.getSession().createSQLQuery(sql2.toString()).list();
			if(list2 != null && list2.size() > 0){
				String sxmc = (String)list2.get(0);
				return sxmc;
			}
		}
		return "";
	}
	
	/**
	 * 根据key从property文件中获取value值
	 * @param localResource
	 * @param key
	 * @return
	 */
	public String getPropertiesValueByKey(ResourceBundle localResource,String key){
		String value = "";
		try {
			value = localResource.getString(key);
		} catch (Exception e) {
			logger.error("没有对应key值为:"+key+SysTraceLogWriter.MESSAGE_SEPARATOR + e.getMessage(), e);
			//e.printStackTrace();
		}
		return value;
	}
	
	/**
	 * 根据分页对象和Form对象进行分页条件查询
	 * @param page 分页对象
	 * @param form Form对象
	 * @return 分页查询结果.附带结果列表及所有查询时的参数
	 */
	@Transactional(readOnly = true)
	public Page<SysCodeForm> searchItem(Page<SysCodeForm> page, SysCodeForm form) {
		// 建立新的分页对象
		Page<SysCodeItem> pg = PageUtils.newPageInstance(page);
		
		// 查询语句及参数
		StringBuffer hql = new StringBuffer("from SysCodeItem ps where 1=1 ");
		List values = new ArrayList();
		
		if(form != null){
			if(StringUtils.isNotBlank(form.getTypeCode())){
				hql.append(" and ps.typeCode = '"+form.getTypeCode()+"'");
			}
			if(StringUtils.isNotBlank(form.getItemCode())){
				hql.append(" and ps.code = '"+form.getItemCode()+"'");
			}
			if(StringUtils.isNotBlank(form.getItemName())){
				hql.append(" and ps.name = '"+form.getItemName()+"'");
			}
		}
		
		//排序
		pg.setOrderBy(SysCodeForm.convertToItemPropertyName(page.getOrderBy()));
		hql.append(HqlUtils.buildOrderBy(pg, "ps"));
		
		// 执行分页查询操作
		pg = sysCodeItemDao.findPage(pg, hql.toString(), values);
		
		// 转换为Form对象列表并赋值到原分页对象中
		List<SysCodeForm> list = SysCodeConverter.convertItemToFormList(pg.getResult());
		PageUtils.copy(pg, list, page);
		return page;
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.augurit.gzcgwsp.wfex.common.service.IWfServiceEX#getDfqx(java.lang.Long, java.lang.String)
	 */
	@Override
	public Date getDfqx(Long ywid, String templateCode) {
		String hql=" select proc from WfBusInstance inst,Jbpm4HistProcinst proc,WfBusTemplate temp where inst.procInstId=proc.procInstId " +
		" and inst.masterEntityKey='"+ywid+"' and inst.templateId=temp.id and temp.templateCode='"+templateCode+"'";
		List list=jbpm4HistTaskDao.find(hql);
		if(list.size()>0){
			Jbpm4HistProcinst proc=(Jbpm4HistProcinst) list.get(0);
			return proc.getProcessDuedate();
		}
		return new Date();
		
	}
}
